package szhn.controller;

import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;
import szhn.model.ResultModel;
import szhn.model.UserModel;
import szhn.model.UserOperationModel;
import szhn.service.SystemService;
import szhn.service.UserService;
import szhn.util.AesUtil;

/**
 * 登陆相关controller
 * @author Panxinxing
 * 2020年4月13日
 *
 */
@RestController
@Slf4j
@RequestMapping("/login")
public class LoginController {
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private SystemService systemService;
	
	
	
	/**
	 * 获取页面加密key
	 * @param request
	 * @return
	 */
	@RequestMapping(value="/aesKey", method = RequestMethod.GET)
	public ResponseEntity<ResultModel> aesKey(HttpServletRequest request) {
		ResultModel result = new ResultModel();
		String aesKey = UUID.randomUUID().toString().substring(0, 16);
		log.info("LoginController获取aesKey={}", aesKey);
		request.getSession().setAttribute("aesKey", aesKey);
		result.setStatus(1);
		result.setData(aesKey);
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 登陆验证
	 * @param request
	 * @param username
	 * @param password
	 * @return
	 */
	@RequestMapping(value="/", method = RequestMethod.POST)
	public ResponseEntity<ResultModel> login(HttpServletRequest request, @RequestParam(value="username") String username, 
			@RequestParam(value="password") String password) {
		log.info("LoginController登陆验证username={}", username);
		ResultModel result = new ResultModel();
		//校验
		if(StringUtils.isEmpty(username)) {
			result.setStatus(0);
			result.setMsg("用户名为空");
			return ResponseEntity.ok(result); 
		}
		if(StringUtils.isEmpty(password)) {
			result.setStatus(0);
			result.setMsg("密码为空");
			return ResponseEntity.ok(result);
		}
		
		
		String aesKey = (String)request.getSession().getAttribute("aesKey");
		if(StringUtils.isEmpty(aesKey)) {
			result.setStatus(0);
			result.setMsg("请刷新页面后再次登陆");
			return ResponseEntity.ok(result);
		}
		String decryptPassword = "";
		String encryptPassword = "";
		try {
			decryptPassword = AesUtil.aesDecrypt(password, aesKey);
			encryptPassword = AesUtil.aesEncrypt(decryptPassword);
		} catch (Exception e) {
			log.error("登陆时解析密码错误");
			result.setStatus(0);
			result.setMsg("登陆超时，请刷新页面后再次登陆");
			return ResponseEntity.ok(result);
		}
		UserModel user = userService.getUserByUsername(username);
		
		if(null == user) {
			result.setStatus(0);
			result.setMsg("用户名错误");
			return ResponseEntity.ok(result);
		}
		
		if(!user.getPassword().equals(encryptPassword)) {
			result.setStatus(0);
			result.setMsg("密码错误");
			return ResponseEntity.ok(result);
		}
		
		//用户操作日志
		UserOperationModel userOperationModel = new UserOperationModel();
		userOperationModel.setId(UUID.randomUUID().toString());
		userOperationModel.setUsername(user.getUsername());
		userOperationModel.setCreateUser(user.getUsername());
		userOperationModel.setOperation("login");
		userOperationModel.setOperationDetail(JSON.toJSONString(user));
		systemService.userOperation(userOperationModel);
		
		request.getSession().setAttribute("user", user);
		result.setStatus(1);
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 修改密码（因原页面中无法识别PUT类型，故改成POST接口）
	 * @param request
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "/modifyPassword", method = RequestMethod.POST)
	public ResponseEntity<ResultModel> modifyPassword(HttpServletRequest request,
			@RequestParam(value = "oldPassword") String oldPassword,
			@RequestParam(value = "newPassword") String newPassword) {
		UserModel user = (UserModel) request.getSession().getAttribute("user");
		log.info("LoginController修改密码username={}", user.getUsername());
		ResultModel result = new ResultModel();

		String aesKey = (String)request.getSession().getAttribute("aesKey");
		if(StringUtils.isEmpty(aesKey)) {
			result.setStatus(0);
			result.setMsg("修改密码时出现异常aesKey");
			return ResponseEntity.ok(result);
		}
		String decryptPassword = "";
		String encryptPassword = "";
		String oldDecryptPassword = "";
		String oldEncryptPassword = "";
		try {
			
			decryptPassword = AesUtil.aesDecrypt(newPassword, aesKey);
			oldDecryptPassword = AesUtil.aesDecrypt(oldPassword, aesKey);
			oldEncryptPassword = AesUtil.aesEncrypt(oldDecryptPassword);
			//判断旧密码是否相同
			if(!oldEncryptPassword.equals(user.getPassword())) {
				result.setStatus(0);
				result.setMsg("旧密码错误");
				return ResponseEntity.ok(result);
			}
			
			//校验密码强度
			if (!checkPassword(decryptPassword)) {
				result.setStatus(0);
				result.setMsg("密码强度过低，请输入字数+大小写字母+特殊字符，且长度大于8位");
				return ResponseEntity.ok(result);
	        }
			encryptPassword = AesUtil.aesEncrypt(decryptPassword);
		} catch (Exception e) {
			log.error("修改密码时出现异常");
			result.setStatus(0);
			result.setMsg("修改密码时出现异常");
			return ResponseEntity.ok(result);
		}
		
		//修改密码
		userService.modifyPassword(user.getUsername(), encryptPassword);
		//刷新session数据
		user.setPassword(newPassword);
		request.getSession().setAttribute("user", user);
		
		//用户操作日志
		UserOperationModel userOperationModel = new UserOperationModel();
		userOperationModel.setId(UUID.randomUUID().toString());
		userOperationModel.setUsername(user.getUsername());
		userOperationModel.setCreateUser(user.getUsername());
		userOperationModel.setOperation("modifyPassword");
		userOperationModel.setOperationDetail("");
		systemService.userOperation(userOperationModel);
		
		result.setStatus(1);
		result.setMsg("修改成功");
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 登出
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/", method = RequestMethod.DELETE)
	public ResponseEntity<ResultModel> operationInfo(HttpServletRequest request) {
		UserModel user = (UserModel) request.getSession().getAttribute("user");
		log.info("LoginController登出username={}", user.getUsername());
		request.getSession().invalidate();
		
		ResultModel result = new ResultModel();
		result.setStatus(1);
		result.setData("登出成功");
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 操作记录
	 * @param request
	 * @param queryUserName
	 * @param operation
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/operationInfo", method = RequestMethod.GET)
	public ResponseEntity<ResultModel> operationInfo(HttpServletRequest request,
			@RequestParam(value = "username", required=false) String queryUserName,
			@RequestParam(value = "operation", required=false) String operation,
			@RequestParam(value = "pageNum", defaultValue="1") int pageNum,
			@RequestParam(value = "pageSize", defaultValue="20") int pageSize) {
		UserModel user = (UserModel) request.getSession().getAttribute("user");
		log.info("LoginController操作记录username={}获取operationInfo参数queryUserName={},operation={},pageNum={},pageSize={}", 
				user.getUsername(), queryUserName, operation, pageNum, pageSize);
		//不是admin用户只能查自己的日志
		/*if(!"admin".equals(user.getUsername())) {
			queryUserName = user.getUsername();
		}*/
		
		PageHelper.startPage(pageNum, pageSize);
		Page<UserOperationModel> list = systemService.userOperationInfo(queryUserName, operation);
		PageInfo<UserOperationModel> pageInfo = new PageInfo<UserOperationModel>(list);
		
		ResultModel result = new ResultModel();
		result.setStatus(1);
		result.setData(pageInfo);
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 查询所有操作人
	 * @return
	 */
	@RequestMapping(value = "/operator", method = RequestMethod.GET)
	public ResponseEntity<ResultModel> queryOperator() {
		log.info("LoginController查询操作人");
		
		List<String> list = systemService.queryOperator();
		
		ResultModel result = new ResultModel();
		result.setStatus(1);
		result.setData(list);
		return ResponseEntity.ok(result);
	}
	
	/**
	 * 校验密码强度
	 * @param password
	 * @return
	 */
	private boolean checkPassword(String password) {
		if (password.matches(".*[a-z]{1,}.*") && password.matches(".*[A-Z]{1,}.*")
				&& password.matches(".*\\d{1,}.*") && password.matches(".*[~!@#$%^&*\\.?]{1,}.*") && password.length() > 7) {
			return true;
		}else {
			return false;
		}
	}
	
	@RequestMapping(value = "/test", method = RequestMethod.GET)
	public ResponseEntity<ResultModel> test(HttpServletRequest request) {
		UserModel user = new UserModel();
		user.setUsername("test");
		user.setType(1);
		request.getSession().setAttribute("user", user);
		
		ResultModel result = new ResultModel();
		result.setStatus(1);
		return ResponseEntity.ok(result);
	}
	
}
